package testcase;

import controller.*;
import view.*;
import information.*;

import java.io.UnsupportedEncodingException;
import java.util.Scanner;
import junit.framework.TestCase;
import org.junit.Test;

/**
 * @author Rigsby Chi (52584035), Lusinda Leung (52571783)
 * @version for Connector.java v1.0.5
 * @since 12-04-2013
 */
public class ConnectorTest extends TestCase {

	// TESTS for initializePierSystem(DisplayView, FileIO,
	// EnrollmentView, int)
	@Test
	public void testInitializePierSystem_normal() {
		class mStub extends DisplayView {
			public void displayFileInHandlingMsg(int state) {
			}
		}

		class fStub extends FileIO {
			public int readNumOfPierFromTxt() {
				return 1;
			}

			public int[] readInfoOfPiersFromTxt(int no) {
				int size[] = new int[1];
				size[0] = 1;
				return size;
			}
			
			public Line[] readLinesFromTxt(int totalNumberOfLine){
				Line line[] = new Line[1];
				line[0] = new Line(1,2,3,4,5);
				return line;
			}
			
		}

		class eStub extends EnrollmentView {
		}

		DisplayView m = new mStub();
		EnrollmentView e = new eStub();
		FileIO f = new fStub();

		Scheduler result = Connector.initializePierSystem(m, f, e, 2);
		assertNotNull(result);
	}

	@Test
	public void testInitializePierSystem_noData_customer() {
		class mStub extends DisplayView {
			public void displayFileInHandlingMsg(int state) {
			}
		}

		class fStub extends FileIO {
			public int readNumOfPierFromTxt() {
				return -1;
			}
		}

		class eStub extends EnrollmentView {
		}

		DisplayView m = new mStub();
		EnrollmentView e = new eStub();
		FileIO f = new fStub();

		Scheduler result = Connector.initializePierSystem(m, f, e, 1);
		assertNull(result);
	}

	@Test
	public void testInitializePierSystem_noData_staff() {
		class mStub extends DisplayView {
			public void displayFileInHandlingMsg(int state) {
			}
		}

		class fStub extends FileIO {
			public int readNumOfPierFromTxt() {
				return -1;
			}
		}

		class eStub extends EnrollmentView {
			public int[] manuallyInitializePiers() {
				int size[] = new int[1];
				size[0] = 1;
				return size;
			}
		}

		DisplayView m = new mStub();
		EnrollmentView e = new eStub();
		FileIO f = new fStub();

		Scheduler result = Connector.initializePierSystem(m, f, e, 2);
		assertNotNull(result);
	}

	@Test
	public void testInitializePierSystem_noData_unknownUser() {
		class mStub extends DisplayView {
			public void displayFileInHandlingMsg(int state) {
			}
		}

		class fStub extends FileIO {
			public int readNumOfPierFromTxt() {
				return -1;
			}
		}

		class eStub extends EnrollmentView {
		}

		DisplayView m = new mStub();
		EnrollmentView e = new eStub();
		FileIO f = new fStub();

		Scheduler result = Connector.initializePierSystem(m, f, e, 3);
		assertNull(result);
	}

	@Test
	public void testInitializePierSystem_damaged() {
		class mStub extends DisplayView {
			public void displayFileInHandlingMsg(int state) {
			}
		}

		class fStub extends FileIO {
			public int readNumOfPierFromTxt() {
				return 1;
			}
			
			public Line[] readLinesFromTxt(int totalNumberOfLine){
				return null;
			}

			public int[] readInfoOfPiersFromTxt(int no) {
				int size[] = new int[1];
				size[0] = 1;
				return size;
			}
		}

		class eStub extends EnrollmentView {
		}

		DisplayView m = new mStub();
		EnrollmentView e = new eStub();
		FileIO f = new fStub();

		Scheduler result = Connector.initializePierSystem(m, f, e, 2);
		assertNull(result);
	}

	// TESTS for viewSchedule(EnrollmentView, Scheduler,
	// DisplayView, boolean)
	@Test
	public void testViewSchedule_normal_customer()
			throws UnsupportedEncodingException {
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return 1;
			}
		}
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int[] getLine(int p, int l) {
				return null;
			}

			public int getSizeOfPier(int p) {
				return 1;
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class mStub extends DisplayView {
			public void printSchedule(int ll[], int pi, int li, int pz) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.viewSchedule(e, t, m, false);
	}

	@Test
	public void testViewSchedule_normal_staff()
			throws UnsupportedEncodingException {
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return 1;
			}

			public boolean askForModification() {
				return false;
			}
		}
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int[] getLine(int p, int l) {
				return null;
			}

			public int getSizeOfPier(int p) {
				return 1;
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class mStub extends DisplayView {
			public void printSchedule(int ll[], int pi, int li, int pz) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.viewSchedule(e, t, m, true);
	}

	@Test
	public void testViewSchedule_noLine() throws UnsupportedEncodingException {
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return -1;
			}
		}
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class mStub extends DisplayView {
		}
		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.viewSchedule(e, t, m, false);
	}

	// TESTS for modifySchedule(EnrollmentView, Scheduler,
	// DisplayView, int, int)
	@Test
	public void testModifySchedule_normal() {
		class eStub extends EnrollmentView {
			public boolean askForModification() {
				return true;
			}

			public Line getLineInfoFromUser(boolean isNew) {
				return null;
			}
		}
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}
		}

		class mStub extends DisplayView {
			public void displayModification(int result) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.modifySchedule(e, t, m, 1, 2);
	}

	@Test
	public void testModifySchedule_invalid() {
		class eStub extends EnrollmentView {
			public boolean askForModification() {
				return true;
			}

			public Line getLineInfoFromUser(boolean isNew) {
				return new Line(1, 1, 1, 1, 1);
			}
		}
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int modifyLine(int p, int l, Line line) {
				return 1;
			}
		}

		class mStub extends DisplayView {
			public void displayModification(int result) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.modifySchedule(e, t, m, 1, 2);
	}

	@Test
	public void testModifySchedule_noModification() {
		class eStub extends EnrollmentView {
			public boolean askForModification() {
				return false;
			}
		}
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}
		}

		class mStub extends DisplayView {
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.modifySchedule(e, t, m, 1, 2);
	}

	// TEST for addSchedule(EnrollmentView, DisplayView, Scheduler)
	@Test
	public void testAddSchedule() {
		class eStub extends EnrollmentView {
			public Line getLineInfoFromUser(boolean isNew) {
				return new Line(1, 1, 1, 1, 1);
			}
		}

		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int timeRegister(Line line) {
				return 1;
			}
		}
		class mStub extends DisplayView {
			public void displayRegistration(int result) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.addSchedule(e, m, t);
	}

	// TESTS for deleteSchedule(EnrollmentView, LogonPage,
	// Scheduler, DisplayView)
	@Test
	public void testdeleteSchedule_normal() {
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return 1;
			}
		}

		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public boolean deleteLine(int p, int l) {
				return true;
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class lStub extends LoginPage {
			public boolean askForPassword() {
				return true;
			}
		}

		class mStub extends DisplayView {
			public void displayDeletion(boolean b1, boolean b2) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();
		LoginPage l = new lStub();

		Connector.deleteSchedule(e, l, t, m);
	}

	@Test
	public void testdeleteSchedule_invalid_password() {
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return 1;
			}
		}

		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class lStub extends LoginPage {
			public boolean askForPassword() {
				return false;
			}
		}

		class mStub extends DisplayView {
			public void displayDeletion(boolean b1, boolean b2) {
			}
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();
		LoginPage l = new lStub();

		Connector.deleteSchedule(e, l, t, m);
	}

	@Test
	public void testDeleteSchedule_noLine() {
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return -1;
			}
		}

		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int getNumberOfLines(int p) {
				return -1;
			}
		}

		class lStub extends LoginPage {
		}

		class mStub extends DisplayView {
		}

		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();
		LoginPage l = new lStub();

		Connector.deleteSchedule(e, l, t, m);
	}
	
	@Test
	public void testExecuteOption() throws UnsupportedEncodingException{
		class cStub extends Connector{
			public void setIdentity(int i){
				identity = i;
			}
		}
		
		class eStub extends EnrollmentView {
			public int selectPier(int numOfPier) {
				return 1;
			}

			public int selectLine(int numOfLine) {
				return -1;
			}
			
			public Line getLineInfoFromUser(boolean newLine) {
				return null;
			}
		}

		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int getNumberOfLines(int p) {
				return -1;
			}
			
			public int timeRegister(Line line){
				return 0;
			}
		}

		class lStub extends LoginPage {
		}

		class mStub extends DisplayView {
		}
		
		class menuStub extends Menu{
			private int returnValue = -1;
			private int case1count = 0;
			public cStub ccStub= new cStub();
			
			@Override
			protected void displayMenu() {}

			@Override
			protected int getNoOfOptions() {
				return 0;
			}
			
			protected int askForOption(Scanner scanner){
				if(returnValue == 1 && case1count == 0){
					case1count ++;
					ccStub.setIdentity(2);
					return returnValue;
				}
				returnValue++;
				return returnValue;
			}
			
		}
		
		Menu menu = new menuStub();
		EnrollmentView e = new eStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView mes = new mStub();
		LoginPage l = new lStub();

		
		cStub.executeOption(l, e, mes, menu, t);
	}
	
	// TESTS for logout(FileIO, DisplayView, Scheduler, boolean)
	@Test
	public void testLogout_normal_customer()
			throws UnsupportedEncodingException {
		class fStub extends FileIO {
		}
		
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}
		}

		class mStub extends DisplayView {
			public void displayTerminateMsg() {
			}
		}

		FileIO f = new fStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.logout(f, m, t, false);
	}
	
	@Test
	public void testLogout_normal_staff()
			throws UnsupportedEncodingException {
		class cStub extends Connector {
			public void setNumOfPiers(int num) {
				numOfPiers = num; 
			}
		}
		
		class fStub extends FileIO {
		}
		
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int[] getLine(int p, int l) {
				int[] line = new int[5];
				for (int i=0; i<5; i++)
					line[i] = i+1;
				return line;
			}

			public int getSizeOfPier(int p) {
				return 1;
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class mStub extends DisplayView {
			public void displayFileOutHandlingMsg(boolean r) {
			}
			
			public void displayTerminateMsg() {
			}
		}

		cStub c = new cStub();
		c.setNumOfPiers(1);
		FileIO f = new fStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.logout(f, m, t, true);
	}

	@Test
	public void testLogout_cantWriteToTxt()
			throws UnsupportedEncodingException {
		class cStub extends Connector {
			public void setNumOfPiers(int num) {
				numOfPiers = num; 
			}
		}
		
		class fStub extends FileIO {
		}
		
		class tStub extends Scheduler {
			public tStub(Pier p[], int pn) {
				super(p, pn);
			}

			public tStub(int ps[]) {
				super(ps);
			}

			public int[] getLine(int p, int l) {
				int[] line = new int[5];
				for (int i=0; i<5; i++)
					line[i] = i+1;
				return line;
			}

			public int getSizeOfPier(int p) {
				return 1;
			}

			public int getNumberOfLines(int p) {
				return 1;
			}
		}

		class mStub extends DisplayView {
			public void displayFileOutHandlingMsg(boolean r) {
			}
			
			public void displayTerminateMsg() {
			}
		}

		cStub c = new cStub();
		c.setNumOfPiers(1);
		FileIO f = new fStub();
		Scheduler t = new tStub(new int[1]);
		DisplayView m = new mStub();

		Connector.logout(f, m, t, true);
	}
}
